package team.nmsg.ge.system.service.impl;

import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;










import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import team.nmsg.ge.system.bean.PageObject;
import team.nmsg.ge.system.bean.SysOper;
import team.nmsg.ge.system.bean.SysRole;
import team.nmsg.ge.system.bean.SysUser;
import team.nmsg.ge.system.dao.INMSCommonDao;
import team.nmsg.ge.system.dao.ISysOperRepository;
import team.nmsg.ge.system.dao.ISysRoleRepository;
import team.nmsg.ge.system.dao.ISysUserRepository;
import team.nmsg.ge.system.dao.ISysUserRoleDao;
import team.nmsg.ge.system.init.shiro.SysAuthorizingRealm;
import team.nmsg.ge.system.service.IUserRoleService;
import team.nmsg.ge.system.util.MD5Encrypt;
import team.nmsg.ge.system.util.ServerConstants;
import team.nmsg.ge.system.util.SysSpringContext;
import team.nmsg.ge.system.util.SysTxSessionRunnable;
import team.nmsg.ge.system.util.SysUtil;

@Transactional
@Service
public class UserRoleServiceImpl implements IUserRoleService{
	
	private static Logger logger =  LoggerFactory.getLogger(  UserRoleServiceImpl.class );
	
	@Autowired
	private ISysUserRepository userRe;
	
	@Autowired
	private ISysRoleRepository roleRe;
	
	@Autowired
	private ISysOperRepository operRe;
	
	@Autowired
	private INMSCommonDao commonDao;
	
	@Autowired
	private ISysUserRoleDao userRoleDao = null;


	@Override
	public boolean updExpiredPassword(SysUser user, String oldPassword, String newPassword) {
		
		
		return false;
	}


	@Override
	public SysUser findUserWithUsernameAndPassword(String uname, String md5Str) {
		
		SysUser user = userRe.findByUsernameAndPassword(uname, md5Str);
		
		Set<SysRole> roles = user.getRoles();
		SysRole next = roles.iterator().next();
		Set<SysOper> opers = next.getOpers();
		int size =opers.size();
		logger.debug(  "findUserWithUsernameAndPassword ::::::::::::"  + size  );
		
		return user;
	}


	@Override
	public void updateUserLoginTimeAndNum(SysUser user) {
		
		SysUser findOne = userRe.findOne(user.getUserId());
		findOne.setLastLoginTimestamp(user.getLastLoginTimestamp());
		findOne.setLoginCounter(user.getLoginCounter());
		userRe.save(findOne);
		
	}


	@Override
	public PageObject<SysUser> QueryUser(int pageSize, int startIndex,
			SysUser criteria) {
		
		StringBuffer queryCountSql = null;
		queryCountSql = new StringBuffer("select count(distinct(user.userId)) ");
		StringBuilder querySql=null;
		querySql = new StringBuilder("select user.* ");
		
		StringBuffer queryAppend = new StringBuffer("from sysuser user ");
		
		String uName = criteria.getUsername();
		if( uName!= null && !"".equals(uName) ){
			queryAppend.append("where username like " + "'%"+uName+"%'");
		}
		queryCountSql.append(queryAppend);
		querySql.append(queryAppend);
		PageObject<SysUser> multiRowBySqlPage = commonDao.getMultiRowBySqlPage(SysUser.class, querySql.toString(), queryCountSql.toString(), startIndex, pageSize, null);
		
		return multiRowBySqlPage;
		
	}


	@Override
	public List<SysRole> findAllRoles() {
		return roleRe.findAll();
	}


	@Override
	public SysUser addSysUser(SysUser user) {
		SysUser save = userRe.save(user);
		return save;
	}
	
	@Override
	public boolean deleteUserByID(String[] UserIds) {
		try{
			for(String id:UserIds){
				SysUser object = userRe.findOne(Integer.valueOf(id));
				if( object != null ){
					userRe.delete(object);
				}
			}
		}catch(Exception e){
			logger.error("",e);
			return false;
		}
		return true;
	}
	
	@Override
	public SysUser queryUserById(Integer id){
		
		return userRe.findOne(id);
		
	}
	
	@Override
	public boolean updUser(SysUser user){
		try{
			Integer useid = user.getUserId();
			SysUser pUser = userRe.findOne(useid);
			if(user.getPassword()!=null){
				pUser.setPassword(user.getPassword());	
			}
		
			pUser.setUserStatus(user.getUserStatus());
			pUser.setUserRemark(user.getUserRemark());
			pUser.setPhoneNo(user.getPhoneNo());
			pUser.setEmail(user.getEmail());
			pUser.setLastUpdateTimestamp(System.currentTimeMillis());
			Set<SysRole> newRoles = user.getRoles();
			pUser.setRoles(newRoles);
			
			userRe.saveAndFlush(pUser);
		}catch(Exception e){
			logger.error("",e);
			return false;
		}
		return true;
	}

	@Override
	public List<SysOper> findAllOpers() {

		List<SysOper> all = operRe.findAll();

		return all;
	}
	
	@Override
	public Set<SysOper> getAuthByRole(String rid){
		SysRole role = roleRe.findOne(Integer.parseInt(rid));
		Set<SysOper> oper = role.getOpers();
		oper.size();
 		return  oper;
	}
	
	@Override
	public SysRole addSysRole(SysRole role) {

		SysRole addRole = roleRe.save(role);

		return addRole;
	}
	
	@Override
	public boolean delSysRole(String rid){
		try{
			Session hSession = commonDao.getHSession();
			StringBuilder moQuerySql = new StringBuilder("delete from sys_u_r where r_id="+rid);
			SQLQuery hSqlQuery = hSession.createSQLQuery(moQuerySql.toString());
			hSqlQuery.executeUpdate();
//			StringBuilder moQuerySql3 = new StringBuilder("delete from nmsroletoarea where r_id="+rid);
//			hSqlQuery = hSession.createSQLQuery(moQuerySql3.toString());
//			hSqlQuery.executeUpdate();
			StringBuilder moQuerySql4 = new StringBuilder("delete from sys_r_o where r_id="+rid);
			hSqlQuery = hSession.createSQLQuery(moQuerySql4.toString());
			hSqlQuery.executeUpdate();
			
			StringBuilder moQuerySqlOEM =new StringBuilder("delete from oem_role where roleId="+rid);
			hSqlQuery = hSession.createSQLQuery(moQuerySqlOEM.toString());
			hSqlQuery.executeUpdate();
			
			StringBuilder moQuerySql2 =new StringBuilder("delete from sysrole where roleId="+rid);
			hSqlQuery = hSession.createSQLQuery(moQuerySql2.toString());
			hSqlQuery.executeUpdate();
			return true;
		}catch (Exception e) {
			logger.error("",e);
			return false;
		}
	} 
	
	@Override
	public boolean updModifyOperToRole( int roleId , String[] operId,String rname){
		
		boolean modifyOperToRole = userRoleDao.updModifyOperToRole(roleId, operId);
		
		return modifyOperToRole;
	}

	@Override
	public boolean updChangePassword(SysUser nmsUser,String oldPassword,String newPassword) {
		// TODO Auto-generated method stub
		if(nmsUser.getPassword().equals(MD5Encrypt.getMD5Str(oldPassword))){
				nmsUser.setPassword(MD5Encrypt.getMD5Str(newPassword));
				userRe.saveAndFlush(nmsUser);
				return true;
			
		}
		return false;
	}
	
	@Transactional(propagation=Propagation.REQUIRED)
	public void test(){
		
		Runnable run = new Runnable(){
//		SysTxSessionRunnable run = new SysTxSessionRunnable(){
//			public void sysRun() {
			public void run() {
				try {
					Thread.sleep( 3000);
				} catch (InterruptedException e) {
				}
				
				IUserRoleService service = SysSpringContext.getService(IUserRoleService.class);
				service.test2();
			}
		};
		
		Thread aa = new Thread( run );
		aa.start();
	}
	
	public void test2(){
		
		SysUser findOne = userRe.findByUsernameAndPassword("root", "4c9184f37cff01bcdc32dc486ec36961");
		
		Set<SysRole> roles = findOne.getRoles();
		SysRole next = roles.iterator().next();
		Set<SysOper> opers = next.getOpers();
		int size =opers.size();
		logger.debug(  "test2 :::::::::::::::::::::::::::::::::::::::"+size  );
	}
	
	@Override
	public JSONArray getAllClientInfo(){
		JSONArray result = new JSONArray();
		
		SessionDAO sessionDAO = SysAuthorizingRealm.getSessionDAO();
		
		Collection<org.apache.shiro.session.Session> activeSessions = sessionDAO.getActiveSessions();
		
		Iterator<org.apache.shiro.session.Session> iterator = activeSessions.iterator();
		while( iterator.hasNext()  ){
			org.apache.shiro.session.Session next = iterator.next();
			JSONObject tmpObj = new JSONObject();
			
			Object isKickOut = next.getAttribute(ServerConstants.SESSION_KEY_KICKOUT);
			//如果被打上踢出标记，则拒绝
			if(isKickOut!= null && isKickOut.toString().equals("true")  ){
				continue;
			}
			String host = next.getHost();
			Object username = next.getAttribute(ServerConstants.SESSION_KEY_USERNAME_STR);
			if( username == null ){
				continue;
			}
			Date loginTime = next.getStartTimestamp();
			tmpObj.put("host", host);
			tmpObj.put("username", username);
			tmpObj.put("loginTime", SysUtil.formatDateWithTime(loginTime ));
			tmpObj.put("isOnline",  true );
			
			result.add(tmpObj);
		}
		
		return result;
	}
	
	@Override
	public List<SysUser> findUserByRoles(Set<SysRole> roles) {
		
		List<SysUser> userList = userRe.findByRolesIn(roles);
		
		return userList;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}
